<?php
/**
 * Here is your custom functions.
 */
declare(strict_types=1);

// 应用公共文件
use App\Admin\Vo\System\QueueMessageVo;
use DI\DependencyException;
use DI\NotFoundException;
use Newbie\Helper\AppVerify;
use Newbie\Helper\Id;
use Newbie\Helper\LoginUser;
use Newbie\NewbieCollection;
use support\Log;
use Webman\Event\Event;

/**
 * 获取容器实例
 * @return DI\Container
 */
function container (): \DI\Container {
    return \support\Container::instance();
}

if (!function_exists('redis')) {

    /**
     * 获取Redis实例
     * @return newbie\Cache\Redis
     * @throws DependencyException
     * @throws NotFoundException
     */
    function redis (): newbie\Cache\Redis {
        return container()->get(newbie\Cache\Redis::class);
    }

}


if (!function_exists('logger')) {

    /**
     * 获取日志实例
     * @param string $name
     * @return \Monolog\Logger
     */
    function logger (string $name = 'default'): \Monolog\Logger {
        return Log::channel($name);
    }

}

if (!function_exists('user')) {
    /**
     * 获取当前登录用户实例
     * @param string $scene
     * @return LoginUser
     */
    function user (string $scene = 'default'): LoginUser {
        return new LoginUser($scene);
    }
}

if (!function_exists('format_size')) {
    /**
     * 格式化大小
     * @param int $size
     * @return string
     */
    function format_size (int $size): string {
        $units = ['B', 'KB', 'MB', 'GB', 'TB', 'PB'];
        $index = 0;
        for ($i = 0; $size >= 1024 && $i < 5; $i++) {
            $size  /= 1024;
            $index = $i;
        }
        return round($size, 2) . $units[$index];
    }
}

if (!function_exists('t')) {
    /**
     * 多语言函数
     * @param string $key
     * @param array $replace
     * @return string
     */
    function t (string $key, array $replace = []): string {
        $acceptLanguage = request()->header('accept-language');
        $language       = !empty($acceptLanguage) ? explode(',', $acceptLanguage)[0] : 'zh_CN';
        $language       = str_replace('zh-CN', 'zh_CN', $language);
        return __($key, $replace, $language);
    }
}

function __ ($key, $replace = [], $language = 'zh_CN') {
    static $files = [];
    $arr = explode('.', $key);
    if (count($arr) > 1) {
        $file = $arr[0];
        $name = $arr[1];
    } else {
        $file = 'lang';
        $name = $key;
    }
    if (!isset($files[$file])) {
        $path = base_path() . '/resource/languages/' . $language . '/' . $file . '.php';
        if (!file_exists($path)) {
            $path = base_path() . '/resource/languages/zh_CN/' . $file . '.php';
            if (!file_exists($path)) {
                return $key;
            }
        }
        $files[$file] = require $path;
    }
    $value = $files[$file][$name] ?? $key;
    return str_replace(array_keys($replace), array_values($replace), $value);
}

if (!function_exists('mine_collect')) {
    /**
     * 创建一个Mine的集合类
     * @param null|mixed $value
     * @return NewbieCollection
     */
    function mine_collect ($value = null): NewbieCollection {
        return new NewbieCollection($value);
    }
}

if (!function_exists('context_set')) {
    /**
     * 设置上下文数据
     * @param string $key
     * @param $data
     * @return void
     */
    function context_set (string $key, $data): void {
        \Webman\Context::set($key, $data);
    }
}

if (!function_exists('context_get')) {
    /**
     * 获取上下文数据
     * @param string $key
     * @return mixed
     */
    function context_get (string $key) {
        return \Webman\Context::get($key);
    }
}

if (!function_exists('app_verify')) {
    /**
     * 获取APP应用请求实例
     * @param string $scene
     * @return AppVerify
     * @throws DependencyException
     * @throws NotFoundException
     */
    function app_verify (string $scene = 'api'): AppVerify {
        return new AppVerify($scene);
    }
}

if (!function_exists('snowflake_id')) {
    /**
     * 生成雪花ID
     * @param int|null $workerId
     * @return String
     * @throws DependencyException
     * @throws NotFoundException|Exception
     */
    function snowflake_id (?int $workerId = null): string {
        try {
            return container()->get(Id::class)->getId($workerId);
        } catch (DependencyException|NotFoundException $e) {
        }
    }
}

if (!function_exists('event')) {
    /**
     * 事件调度快捷方法
     * @param string $name
     * @param mixed $data
     * @return array|mixed|null
     */
    function event (string $name, mixed $data) {
        return Event::emit($name, $data);
    }
}

if (!function_exists('push_queue_message')) {
    /**
     * 推送消息到队列
     * @param QueueMessageVo $message
     * @param array $receiveUsers
     * @return int 消息ID，若失败返回 -1
     * @throws Throwable
     * @throws \Psr\Container\ContainerExceptionInterface
     * @throws \Psr\Container\NotFoundExceptionInterface
     */
    function push_queue_message (QueueMessageVo $message, array $receiveUsers = []): int {
        return container()
            ->get(\app\Admin\Service\System\SystemQueueLogService::class)
            ->pushMessage($message, $receiveUsers);
    }
}

if (!function_exists('add_queue')) {
    /**
     * 添加任务到队列
     * @param \app\Admin\Vo\System\AmqpQueueVo $amqpQueueVo
     * @return bool
     * @throws Throwable
     * @throws \Psr\Container\ContainerExceptionInterface
     * @throws \Psr\Container\NotFoundExceptionInterface
     */
    function add_queue (\app\Admin\Vo\System\AmqpQueueVo $amqpQueueVo): bool {
        return container()
            ->get(\app\Admin\Service\System\SystemQueueLogService::class)
            ->addQueue($amqpQueueVo);
    }
}